package com.shop.loan.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shop.loan.model.common.Constant;
import com.shop.loan.service.AsyncService;
import com.shop.loan.util.BlackUtil;
import com.shop.loan.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import xyz.erupt.core.exception.EruptApiErrorTip;
import xyz.erupt.core.view.EruptApiModel;
import xyz.erupt.core.view.Page;
import xyz.erupt.upms.model.EruptUser;
import xyz.erupt.upms.service.EruptUserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Slf4j
@Component
@Aspect
@Order(1)
public class EruptLogAspect {

    @Resource
    BlackUtil blackUtil;

    @Resource
    HttpServletRequest request;

    @Resource
    EruptUserService eruptUserService;

    @Resource
    AsyncService asyncService;

    @Resource
    Util util;


    @Pointcut("execution(* xyz.erupt.core.controller.*.*(..)) || execution(* xyz.erupt.upms.controller.*.*(..))")
    private void controllerAop() {
    }

    @Around("controllerAop()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest httpServletRequest = attributes.getRequest();
        String requestPath = httpServletRequest.getServletPath();
        long startTime = System.currentTimeMillis();
        util.logParam(requestPath, httpServletRequest, startTime);

        if (blackUtil.checkIsBlacklist(httpServletRequest)) {
            throw new EruptApiErrorTip("ip存在异常，请联系管理员", EruptApiModel.PromptWay.MESSAGE);
        }
//        if (!blackUtil.checkIpRegion(httpServletRequest)) {
//            throw new EruptApiErrorTip("ip地区异常", EruptApiModel.PromptWay.MESSAGE);
//        }

        if (!requestPath.contains("/login")) {
            if (blackUtil.checkIpChange(httpServletRequest)) {
                throw new EruptApiErrorTip("ip变更，请重新登录", EruptApiModel.PromptWay.MESSAGE);
            }
        }
        Object obj = joinPoint.proceed();
        if (requestPath.contains("data/table/UserOrderBy") || requestPath.contains("data/table/UserOrderPool")
                || requestPath.contains("data/table/RentalDataBalanceLog")  ||
                (requestPath.contains("/data/UserOrder") && requestPath.contains("/drill/"))
        ) {
            if (obj instanceof Page) {
                Page pageData = (Page) obj;
                JSONObject dataJs = JSON.parseObject(JSON.toJSONString(obj));
                JSONArray list = dataJs.getJSONArray("list");
                if (list != null && list.size() > 0) {
                    JSONObject itemJs = JSON.parseObject(list.get(0).toString());
                    if (itemJs.containsKey("pageIndex")) {
                        pageData.setPageIndex(itemJs.getInteger("pageIndex"));
                        pageData.setPageSize(itemJs.getInteger("pageSize"));
                        pageData.setTotal(itemJs.getLong("total"));
                        pageData.setTotalPage(itemJs.getInteger("totalPage"));
                    }
                }
            }
        }
        return obj;
    }

    @AfterReturning(returning = "result", pointcut = "controllerAop()")
    public void AfterReturning(Object result) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Long startTime = (Long) request.getAttribute(Constant.ATTRIBUTES_TIME_KEY);
        if (startTime != null) {
            Long executeTime = (System.currentTimeMillis() - startTime);
            log.info("请求:{} 结束---,耗时:{} 毫秒，时间标识:{}", request.getServletPath(), executeTime, startTime);
        }
        updateLog(request.getServletPath());
    }

    private void updateLog(String requestPath) {
        EruptUser eruptUser = eruptUserService.getCurrentEruptUser();
        if (eruptUser != null) {
            asyncService.updateOpLog(requestPath, eruptUser.getName(), request.getMethod(), request.getRequestURL().toString());
        }

    }

}
